<?php defined('SYSPATH') or die('No direct script access.');
/**
 * 易宝充值卡支付响应处理
 *
 * @author  Yellow.Chow <aultoale@gmail.com>
 * @version $Id: tenpay.php 199 2012-05-09 08:32:18Z yellow.chow $
 * @license http://www.gnu.org/licenses/gpl-3.0.html    GPL 3
 */
class Payment_Respond_Yeepay_Card extends Payment_Respond
{

    /**
     * 分析返回的结果
     *
     * @param  array  $params
     * @return array
     */
    public function parse(array $params)
    {
        if (isset($params['p3_Amt']))
        {
            $params['p3_Amt'] = number_format($params['p3_Amt'], 2, '.', '');
        }

        return parent::parse($params);
    }

    /**
     * 获取订单号
     *
     * @return string
     */
    public function get_id()
    {
        return $this->get('p2_Order');
    }

    /**
     * 获取支付交易号
     *
     * @return string
     */
    public function get_payment_no()
    {
        return $this->get('p5_CardNo');
    }

    /**
     * 获取数据签名
     *
     * @return string
     */
    public function get_sign()
    {
        return $this->get('hmac');
    }

    /**
     * 获取订单总金额
     *
     * @return float
     */
    public function get_amount()
    {
        return $this->get('p3_Amt');
    }

    /**
     * 获取付款时间
     *
     * @return int
     */
    public function get_time()
    {
        return time();
    }

    /**
     * 获取支付状态
     *
     * @return int
     */
    public function get_status()
    {
        return ($this->get('r1_Code', 0) == 1) ? Payment::STAT_PAID : Payment::STAT_FAILED;
    }

    /**
     * 生成 HMAC 编码
     *
     * @param  string   $data
     * @param  string  $key
     */
    protected function _hmac($data, $key)
    {
        // RFC 2104 HMAC implementation for php.
        // Creates an md5 HMAC.
        // Eliminates the need to install mhash to compute a HMAC
        // Hacked by Lance Rushing(NOTE: Hacked means written)

        $b = 64; // byte length for md5
        if (strlen($key) > $b)
        {
            $key = pack("H*", md5($key));
        }
        $key = str_pad($key, $b, chr(0x00));
        $ipad = str_pad('', $b, chr(0x36));
        $opad = str_pad('', $b, chr(0x5c));
        $k_ipad = $key ^ $ipad ;
        $k_opad = $key ^ $opad;

        return md5($k_opad . pack("H*",md5($k_ipad . $data)));
    }

    /**
     * 验证数字签名
     *
     * @throws Exception
     */
    protected function _verify()
    {
        extract(empty($_GET) ? $_POST : $_GET);

        $data = $r0_Cmd.$r1_Code.$p1_MerId.$p2_Order.$p3_Amt.$p4_FrpId.$p5_CardNo.$p6_confirmAmount.$p7_realAmount.$p8_cardStatus.$p9_MP.$pb_BalanceAmt.$pc_BalanceAct;

        $sign = $this->_hmac(iconv('GB2312', 'UTF-8', $data), $this->_key);

        if ($sign != $this->get_sign())
        {
            throw new Payment_Exception('数字签名认证失败');
        }
    }

}